          SUBROUTINE (MAT OE.VARS,MAT OE.SFLAGS,GROUP,QO,LARGEST.UM,ALLOC.ZONE,LDID.LIST,UPD.LOC,MSG.FLAG,MSGS,RESPS)
** Version# 132.0004[1] - 12/22/2016 - 10:35am - TSMITH - eclipse
*** V132.0003 Change - Custom Coding . - 04/01/2016 - TSMITH - eclipse
*** V132.0002 Change - Custom Coding . - 01/06/2016 - TSMITH - eclipse
*** V132.0001 Change - Custom Coding . - 06/11/2015 - TSMITH - eclipse

*** Subroutine - OE.UPD.QO
*-------------------------------------------------------------------------*
*** This updates the quantity ordered for a line item.
*-------------------------------------------------------------------------*
*** OE.VARS     - OID, GEN, etc. (see CC OE.EQUATES)               [IN]
*** OE.SFLAGS   - Order Entry Screen Dispay Flags                  [IN/OUT]
*** GROUP       -
*** QO          - The quantity orderd                              [IN]
*** LARGEST.UM  - The largest UM to display the quantity orderd in [IN]
*** ALLOC.ZONE  - The allocation zone                              [IN]
*** LDID.LIST   - This is a VM list of LDIDs for the current gen.  (IN)
***             - This only needs to be updated when a new LDID
***             - has yet to be added to the order.
*** UPD.LOC     - This is used to avoid running the same code      [IN/OUT]
***             - over and oven (when uncessary).  The first time
***             - this is called, UPD.LOC should be "".  This
***             - routine will update the value of UPD.LOC and
***             - expect that same value to be passed back.
*** MSG.FLAG    - Boolean, if this is true, then an action has     (OUT)
***             - been added to the MSGS array that requires user
***             - interaction.  Also, this update routine should
***             - be called again with the appropriate responces.
*** MSGS        - The actions array.                               [IN/OUT]
*** RESPS       - The responces array.                             [IN/OUT]
*-------------------------------------------------------------------------*
*** Common: Requrires all the common arrays used in OE...
***       LED, LD, CUS, CUSS, PLNE, PRD, MA, OID.DATA$, etc...
*-------------------------------------------------------------------------*
          $INCLUDE CC OE.EQUATES
          DIM MAD(7)

          IF RESPS<1,1> = 'EXEMPT' THEN
             EXEMPT.FLAG = 1
          END ELSE
             EXEMPT.FLAG = ''
          END
          IS.RESERVE = NO
          *Check to see if this is a reserve order.
          IF USE.RESERVE$ AND MODE%='S' THEN
             LOCATE 'R' IN LED(6)<1> SETTING RSPOS THEN
                IS.RESERVE = YES
             END
          END

          *** set consignment billing flag
          IF LED(110)<1,1> = 'B' THEN CONSIGN = 1 ELSE CONSIGN = 0

          PRC.BR    = LED(2)<1,GEN%,1>
          STK.BR    = LED(2)<1,GEN%,2>
          MSG.FLAG  = NO
          IS.PN     = (NUM(LD(1)) AND LD(1) # '')
          *** Only update the quantity for a product.
          IF NOT(IS.PN) THEN RETURN
          QO = QO+0
          IF MODE% = 'T' AND NOT(QO) THEN RETURN
          IF QO = 0 AND LD(4)+0 = 0 THEN
             *** An order quantity is required.
             MSG.FLAG = YES
             ACTION.ADD.MSG MSGS,,YES,'%36',,,,5,3
             RETURN
          END
          * If the Qty has been changed mid-process by the code.  (e.g.
          * non-manually...)
          MOD.QO      = 'OE.UPD.QO~MOD.QO'
          LOCATE MOD.QO IN RESPS<1> SETTING RPOS THEN
             NEW.QO   = RESPS<2,RPOS>

             * If the new order qty is not 0, and the new qty doesn't
             * agree with the QO passed in, opt for the NEW.QO...
             IF NEW.QO+0 # 0 AND NEW.QO # QO THEN
                QO    = NEW.QO
             END
          END

START:    *** The beginning of the logic.
          LD(23) = LARGEST.UM
          READ ORD.UOM FROM CTRLFILE,'OE.USE.ORDER.UOM' ELSE ORD.UOM=''
          IF ORD.UOM THEN
             LD(85) = LARGEST.UM
          END

          LD(41) = ALLOC.ZONE

          *** If Misc Charge Item, Exclude from Sales index.
          IF PRD(3)=3 THEN LD(42)<1,1> = 1 ELSE LD(42)<1,1> = ''

          OE.CALC.QOPEN OID%,QSIGN%,QOPEN,GEN%
          QO.DIFF = QO - QOPEN

          BEGIN CASE
          CASE UPD.LOC =   5;   GOTO UPD.5
          CASE UPD.LOC =  10;   GOTO UPD.10
          CASE UPD.LOC =  15;   GOTO UPD.15
          CASE UPD.LOC =  20;   GOTO UPD.20
          CASE UPD.LOC =  30;   GOTO UPD.30
          CASE UPD.LOC =  40;   GOTO UPD.40
          CASE UPD.LOC =  50;   GOTO UPD.50
          CASE UPD.LOC =  60;   GOTO UPD.60
          CASE UPD.LOC =  70;   GOTO UPD.70
          CASE UPD.LOC =  75;   GOTO UPD.75
          CASE UPD.LOC =  80;   GOTO UPD.80
          CASE UPD.LOC =  90;   GOTO UPD.90
          CASE UPD.LOC = 100;   GOTO UPD.100
          CASE UPD.LOC = 110;   GOTO UPD.110
          CASE UPD.LOC = 120;   GOTO UPD.120
          CASE UPD.LOC = 130;   GOTO UPD.130
          CASE UPD.LOC = 135;   GOTO UPD.135
          CASE UPD.LOC = 140;   GOTO UPD.140
          CASE UPD.LOC = 150;   GOTO UPD.150
          CASE UPD.LOC = 160;   GOTO UPD.160
          CASE UPD.LOC = 165;   GOTO UPD.165
          CASE UPD.LOC = 170;   GOTO UPD.170
          CASE UPD.LOC = 180;   GOTO UPD.180
          CASE UPD.LOC = 200;   GOTO UPD.200
          CASE UPD.LOC = 210;   GOTO UPD.210
          CASE UPD.LOC = 215;   GOTO UPD.215
          CASE UPD.LOC = 220;   GOTO UPD.220
          END CASE

UPD.5:    UPD.LOC =   5;  GOSUB CHECK.WIP.SPLIT.QTY
UPD.10:   UPD.LOC =  10;  GOSUB CHECK.MJB
UPD.15:   UPD.LOC =  15;  GOSUB CHECK.SHIPMENT
UPD.20:   UPD.LOC =  20;  GOSUB CHECK.SIGN
UPD.30:   UPD.LOC =  30;  GOSUB CHECK.PACKAGE.QTY
UPD.40:   UPD.LOC =  40;  GOSUB CHECK.MAX.DAYS
UPD.50:   UPD.LOC =  50;  GOSUB CHECK.INV.FACTOR
UPD.60:   UPD.LOC =  60;  GOSUB CHECK.BUY.PACKAGE
UPD.70:   UPD.LOC =  70;  GOSUB CHECK.CREDIT.QTY
UPD.75:   UPD.LOC =  75;  GOSUB CHECK.RETURN.QTY.OK
UPD.80:   UPD.LOC =  80;  GOSUB CHECK.DELETE
UPD.90:   UPD.LOC =  90;  GOSUB CHECK.PURGE
UPD.100:  UPD.LOC = 100;  GOSUB CHECK.TAG
UPD.110:  UPD.LOC = 110;  GOSUB CHECK.INV.AVAIL
UPD.120:  UPD.LOC = 120;  GOSUB CHECK.INV.CREDIT
UPD.130:  UPD.LOC = 130;  GOSUB ADD.COMMENT
UPD.135:  UPD.LOC = 135;  GOSUB CHECK.BRANCH.AUTH
UPD.140:  UPD.LOC = 140;  GOSUB UPDATE.QO
UPD.150:  UPD.LOC = 150;  GOSUB CHECK.DELETE.ITEM
UPD.160:  UPD.LOC = 160;  GOSUB CHECK.SPLIT.QTY
UPD.165:  UPD.LOC = 165;  GOSUB SHOW.BR.INVS
UPD.170:  UPD.LOC = 170;  GOSUB CHECK.SCHEDULE
UPD.180:  UPD.LOC = 180;  GOSUB CHECK.DISP.LOC
UPD.200:  UPD.LOC = 200;  GOSUB CHECK.RETURN
UPD.210:  UPD.LOC = 210;  GOSUB CHECK.DETAIL.LOT
UPD.215:  UPD.LOC = 215;  GOSUB CHECK.CUT
UPD.220:  UPD.LOC = 220;  GOSUB CHECK.CUSTOM
          RETURN
*-------------------------------------------------------------------------*
CHECK.MJB:*** Check to see if we need to limit OQ editing...
          ACT.ID  = 'MJB.AUTH'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END

          * Only need to check for MJBs or Jr Ords.
          IF NOT(LED(129)<1,1>) AND NOT(LED(128)<1,1>) THEN RETURN

          * Set up vars of what we're interested in authing...
          DO.AUTH  = NO
          OLD.QO   = LD(4)
          OLD.PN   = OLD.LD(1)

          BEGIN CASE
          CASE OLD.QO # LD(4);    DO.AUTH = YES     ;* Chg QO.
          CASE OLD.PN # LD(1);    DO.AUTH = YES     ;* New PN or Chg PN.
          CASE OTHERWISE;         NULL
          END CASE

          * If there's no cause for concern, then don't do this auth.
          IF NOT(DO.AUTH) THEN RETURN

          * If we've checked the auth, see what the result was, otherwise
          * at this point we need to check the auth.
          LOCATE ACT.ID IN RESPS<1> SETTING RESP.POS THEN
             ACTION.OK = RESPS<2,RESP.POS,1>
             IF NOT(RESPS<2,RESP.POS,1>) THEN
                MSG.FLAG = NO
                RETURN TO FINISH
             END
          END ELSE
             OE.MJB.AUTH.REQD OID%,IS.AUTH.REQD
             IF (IS.AUTH.REQD) THEN
                KEY       = 'SOE.MASTER.BID.EDIT'
                CHECK.KEY KEY,,KEY.LEVEL
                IF KEY.LEVEL < 4 THEN
                   PRMPT     = '%194'
                   IF LED(129)<1,1> THEN PRMPT = '%195'
                   ACTION.ADD.AUTH MSGS,ACT.ID,,PRMPT,,KEY,3,,OID%,GEN%
                   MSG.FLAG  = YES
                   RETURN TO FINISH
                END
             END ELSE
                KEY.LEVEL = 4
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.SHIPMENT: * Check qty ordered vs. qty on shipment.  If qty ordered is
              * reduced to less than qty on shipment then disallow entry.
          GOSUB GET.ASN.ID
          IF MODE% = 'P' AND ASN.ID AND (LED(6)<1,GEN%> = 'O' OR LED(6)<1,GEN%> = 'R') THEN
             IF QO < ASN.SHP.QTY THEN
                UT.GET.PROMPT '%600',PRMPT
                PRMPT     = ASN.SHP.QTY:PRMPT
                ACTION.ADD.AUTH MSGS,ACT.ID,,PRMPT,,,,,OID%,GEN%
                MSG.FLAG  = YES
                RETURN TO FINISH
             END
          END
          RETURN
*-------------------------------------------------------------------------*
GET.ASN.ID:
          * Get Shipment ID for Transfers/Purchase Orders
          * and restrict changes.
          ASN.ID     = ''
          ASN.STATUS = ''
          ASN.SHP.QTY= ''
          BEGIN CASE
          CASE MODE% = 'T'
             ASN.ID = ASN.ID.GET(OID%,LED(12)<1,GEN%>,LDID%,ASN.SHP.QTY
          CASE MODE% = 'P'
             IF LED(6)<1,GEN%> = 'O' THEN
                * If any Vgen is on an ASN lock the line
                LOCATE 'V' IN LED(6)<1> SETTING VGEN THEN
                   GEN.CNT = DCOUNT(LED(6),VM)
                   FOR G = 1 TO GEN.CNT UNTIL ASN.ID
                      IF LED(6)<1,G> = 'V' THEN
                         ASN.ID = ASN.ID.GET(OID%,LED(12)<1,G>,LDID%,ASN.SHP.QTY
                      END
                   NEXT G
                END
             END ELSE
          *EJO  ASN.ID = ASN.ID.GET(OID%,LED(12)<1,GEN%>,LDID%,ASN.SHP.QTY
                ASN.ID = ASN.ID.GET(OID%,LED(12)<1,GEN%>)
             END
          END CASE

          RETURN

          RETURN
*-------------------------------------------------------------------------*
CHECK.SIGN:*** This makes sure that the user doesn't change the sign of
           *** the order for a line item that has been shipped on more
           *** than one order.
          ACT.ID  = 'CHECK.SIGN'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END

          IF MODE% = 'T' AND QO < 0 THEN
             *** Never do transfer for neg qty...  Just switch the BRs,
             *** and do a transfer that way...
             ACTION.ADD.MSG MSGS,,YES,'%9',,YES,YES,5,10
             RETURN TO FINISH
          END

          OLD.QO   = LD(4) * QSIGN%
          SHIP.QTY = (SUM(LD(5)<1,GEN%>) + SUM(LD(6)<1,GEN%>)) * QSIGN%

          BEGIN CASE
          CASE QO+0 = 0;          NULL  ;* No new quantity
          CASE OLD.QO / QO >= 0;  NULL  ;* No change in sign
          CASE OLD.QO = SHIP.QTY; NULL  ;* Order Qty = Ship Quantity
          CASE OTHERWISE;
             ACTION.ADD.MSG MSGS,,YES,'%19',,,YES
             RETURN TO FINISH
          END CASE

          RETURN
*-------------------------------------------------------------------------*
CHECK.PACKAGE.QTY:***
          ACT.ID  = 'AUTH.PACKAGE.QTY'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END

          * Check to see if we should skip the Minimum Package Quantity
          * check. This is the case if the product is being cut. We do
          * not have minimum quantity restrictions on cut products.
          CUT.ID = "OE.LI.COMMIT.CUT"

          * If we find OE.LI.COMMIT.CUT in the responses then it means
          * this product - which has not bee added to the order yet - is
          * going to be cut after being added, so there is no need to
          * check the quantity.
          LOCATE CUT.ID IN RESPS<1> SETTING NOTHING THEN
             RETURN
          END ELSE
             * If we didn't locate OE.LI.COMMIT.CUT, we still need to
             * check to see if this is a cuttable product. If the user
             * is adding a product to the cut screen directly off of
             * Order Entry, OE.LI.COMMIT.CUT isn't going to be used.
             CUTTABLE = NO
             IS.PRODUCT.CUTTABLE OID%,GEN%,CUTTABLE,,YES
             IF CUTTABLE THEN RETURN
          END

          PRD.BR.GET.VAL STK.BR,LD(1),1,MIN.OQ
          MIN.PCK = MIN.OQ

          * Check control record to determine if the quantity must be
          * in multiples of the sell package quantity on return items
          CTRL.ID = "MIN.PACKAGE.RETURNS"
          READV REQ.RET FROM CTRLFILE,CTRL.ID,1 ELSE REQ.RET = ""
          QO.OK    = ((QO > 0) OR (QO < 0 AND REQ.RET))

          * Save the return sign for later use
          RET.SIGN = (QO / ABS(QO))

          IF NOT((MODE% = 'S' OR MODE% = "T") AND MIN.OQ > 1) THEN RETURN
          IF NOT(QO.OK)                      THEN RETURN
          IF INT(QO/MIN.PCK) = QO/MIN.PCK    THEN RETURN
          *if use reserve inventory and the one of the
          *status is R, don't bother checking it.
          IF IS.RESERVE THEN RETURN

          DFLT.PER.GET 'S',PER,ALPHA
          LOCATE ACT.ID IN RESPS<1> SETTING RESP.POS THEN
             ACTION.OK = RESPS<2,RESP.POS,1>
             IF NOT(ACTION.OK) THEN
                QO = (MIN.PCK * (INT(QO / MIN.PCK) + 1)) * RET.SIGN
                QO.DIFF = QO - QOPEN

                * Include a response for modifying the order quantity.
                * OE.LI.COMMIT know how to handle this message.
                RESP.CT = DCOUNT(RESPS<1>,VM)
                RESPS<1,RESP.CT+1> = "OE.UPD.QO~SPKG.QO"
             END
          END ELSE
             UT.GET.PROMPT '%20':AM:(MIN.PCK/PER):AM:ALPHA,PRMPT
             PRMPT.LOG = PRMPT:' with ':QO:' ^':LD(1):' ':PRD(1)<1,1>
             KEY       = 'SOE.PACKAGE.QTY'
             MSG.FLAG  = YES

             IF CONSIGN THEN LEV = 1 ELSE LEV = 2
             ACTION.ADD.AUTH MSGS,ACT.ID,,PRMPT,,KEY,LEV,PRMPT.LOG,OID%,GEN%
             RETURN TO FINISH
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.MAX.DAYS: *** Check the maximum days supply
          ACT.ID  = 'PIL.AUTH'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END

          IF (MODE% = "W")        THEN RETURN
          IF LED(6)<1,GEN%> = 'B' THEN RETURN

          *if use reserve inventory and the one of the
          *status is R, don't bother checking it.
          IF IS.RESERVE THEN RETURN

          OE.PIL.CHECK.BODY MAT OE.VARS,QO,NO,PIL.OK,MSG.ADDED,MSGS,RESPS

          IF MSG.ADDED THEN MSG.FLAG = YES
          IF NOT(PIL.OK) OR MSG.ADDED THEN RETURN TO FINISH

          RETURN
*-------------------------------------------------------------------------*
CHECK.INV.FACTOR: *** Check the order to inventory factor
          ACT.ID  = 'CHECK.INV.FACTOR'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END

          IF LED(6)<1,GEN%> = 'B' THEN RETURN   ;* Do Not Check Bids
          IF POST.ENTRY% THEN RETURN  ;*Do not check post oe
          *if use reserve inventory and the one of the
          *status is R, don't bother checking it.
          IF IS.RESERVE THEN RETURN

          OLD.QO = LD(4) * QSIGN%
          PN = LD(1)

          ORD.INV.FAC.CHECK GEN%,PN,MODE%,QO,OLD.QO,UPD.OK,ALLOW.FCTR
          IF UPD.OK = NO THEN
             ACT.ID = 'QO.INV.OVRD'
             LOCATE ACT.ID IN RESPS<1> SETTING OVRD.POS THEN
                YN.RESP = RESPS<2,OVRD.POS>
                IF YN.RESP = YES THEN
                   SCHED.ACTIVE% = 2 ;* Force Scheduling Open
                   OE.SEND.JOB.QUEUE OID%,LED(1)<1,GEN%>,LD(1),STK.BR
                END ELSE
                   SCHED.ACTIVE% = NO
                   RETURN TO FINISH
                END
             END ELSE
                MSG.TEXT      = '%21':AM:ALLOW.FCTR:AM:''
                MSG.FLAG      = YES
                SCHED.ACTIVE% = NO
                ACTION.ADD.PROMPT MSGS,ACT.ID,,MSG.TEXT,,,'YN',1,'Y'
                RETURN TO FINISH
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.BUY.PACKAGE:*** Routine to check the buy package qty for this product
          ACT.ID  = 'CHECK.BUY.PACKAGE'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF MODE% # 'P' THEN RETURN
          IF QO <= 0     THEN RETURN

          *** Get the buy package for this br.
          DFLT.PER.GET 'P',BPER,BALPHA
          PRD.BR.GET.VAL LED(2)<1,GEN%,1>,LD(1),4,BUYPKG
          IF BUYPKG < 1 THEN BUYPKG = 1

          *** Check that the Quantity on order is divisible by the pkg.
          IF MOD(QO,BUYPKG) # 0 THEN
             PRD.BR.GET.VAL LED(2)<1,GEN%,1>,LD(1),27,DIV
             IF DIV = 'O' THEN DIV = ''
             BPKG = PERCONV(BUYPKG,BPER,0)
             IF NOT(DIV) THEN
                TEXT = '%22'
             END ELSE
                TEXT = '%23'
             END
             TEXT<2> = BPKG:BALPHA "L#2"

             *** Warn the user that there is a package quantity.
             ACTION.ADD.MSG MSGS,,,TEXT,,,,5,3
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.CREDIT.QTY: *** If this is a credit order, then make sure that the
                  *** user has the authority to update the quantity.
          ACT.ID  = 'CHECK.CREDIT'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF QO >= 0 THEN RETURN
          IF IS.RESERVE THEN RETURN
          IF MODE% = 'W' THEN RETURN

          KEY = MODE%:'OE.CREDIT.QTY'

          CHECK.KEY KEY,CRED.OK
          IF NOT(CRED.OK) THEN
             LOCATE KEY IN RESPS<1> SETTING NOTHING ELSE
                * Display the specific order type error message based on
                * the mode the user in is.
                BEGIN CASE
                   CASE MODE% = 'P'
                      PRMPT = '%154'
                   CASE MODE% = 'T'
                      PRMPT = '%156'
                   CASE OTHERWISE
                      PRMPT = '%24'
                END CASE
                ACTION.ADD.AUTH MSGS,KEY,YES,PRMPT,,KEY,,,OID%,GEN%
                MSG.FLAG = YES
                RETURN TO FINISH
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.RETURN.QTY.OK: *** Check to see if the quantity change on a return
          *** Sales Order will result in the original order exceeding its
          *** return limit.

          * Only valid for Sales Orders
          IF (MODE% # "S") THEN RETURN

          * Check to see if the question has been asked.
          ACT.ID = "SOE.RETURN.ALLOWED.ORIG.EXCEEDED"
          LOCATE ACT.ID IN RESPS<1> SETTING RESP.POS THEN
             ACTION.OK = RESPS<2,RESP.POS,1>

             * If it has ben asked, proceed based on the answer.
             IF ACTION.OK THEN
                RETURN
             END ELSE
                MSG.FLAG = NO
                RETURN TO FINISH
             END
          END

          * Pull the return order info, old quantity and new quantity.
          ORIG.ORD    = LD(44)
          OLD.RET.QTY = SUM(LD(5)<1,GEN%>) + SUM(LD(6)<1,GEN%>)
          NEW.RET.QTY = -QO


          * If this is a return (and we have an original order).
          IF ((NEW.RET.QTY > 0) AND (ORIG.ORD # "")) THEN

             * Check to see if we are in violation of the original order.
             SOE.RETURN.CHECK.QTYS OID%,GEN%,LDID%,OLD.RET.QTY,NEW.RET.QTY,ORIG.ORD,RET.ERROR.MSG,LOCK.MSG

             * If a lock was found do not continue.
             IF LOCK.MSG THEN
                MSG.FLAG = YES
                ACTION.ADD.MSG MSGS,,YES,LOCK.MSG,,YES,YES,5,10
                RETURN TO FINISH
             END

             * If we are in violation...
             IF RET.ERROR.MSG THEN
                * See if the user is allowed to return against an order
                * that has reached/exceeded its return limit.
                KEY.REQD = "SOE.RETURN.ALLOWED"
                PROMPT   = RET.ERROR.MSG

                * Only need level 1 auth for stock items.
                IF PRD(3) = 1 THEN LVL.REQD = 1 ELSE LVL.REQD = 2
                ACTION.ADD.AUTH MSGS,ACT.ID,YES,PROMPT,,KEY.REQD,LVL.REQD,PROMPT,OID%,GEN%
                MSG.FLAG = YES
                RETURN TO FINISH
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.DELETE:*** Check for deleted status & stock levels & authorization
          IF IS.RESERVE THEN RETURN
          ACT.ID  = 'CHECK.DELETE'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          PN = LD(1)
          BR = LED(2)<1,GEN%,2>
          * When the product is overwritten in OE with a new product, the
          * open quantity should be 0 and should not be pulled from the
          * open quantity of the overwritten product
          IF OLD.LD(1) AND OLD.LD(1) # LD(1) THEN
             QO.DIFF2 = QO
          END ELSE
             QO.DIFF2 = QO - QOPEN
          END
          OE.CHK.DEL MAT OE.VARS,BR,PN,QO.DIFF2,MSG.FLAG,MSGS,RESPS

          IF MSG.FLAG THEN RETURN TO FINISH

          RETURN
*-------------------------------------------------------------------------*
CHECK.PURGE:*** Do not add a purge item onto an order
          ACT.ID  = 'CHECK.PURGE'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF IS.RESERVE THEN RETURN
          IF PRD(3) = 7 THEN
             ACTION.ADD.MSG MSGS,,YES,'%33',,,,2,3
             RETURN TO FINISH
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.TAG:*** Make sure that the user isn't effecting a tag item
          ACT.ID  = 'OE.TAG.CHECK'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF IS.RESERVE THEN RETURN
          IF QO.DIFF >= 0 THEN RETURN

          OE.TAG.CHECK MAT OE.VARS,QO.DIFF,CHNG.OK,MSG.FLAG,MSGS,RESPS
          IF MSG.FLAG OR NOT(CHNG.OK) THEN RETURN TO FINISH

          RETURN
*-------------------------------------------------------------------------*
CHECK.INV.AVAIL:*** Check Avail if we're adding qtys to an invoice.
          ACT.ID  = 'CHECK.INV.AVAIL'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF QO.DIFF <= 0         THEN RETURN
          IF MODE%    # 'S'       THEN RETURN
          IF NOT(LED(8)<1,GEN%>)  THEN RETURN
          IF IS.RESERVE THEN RETURN

          *** See if the site is even set up to check the avail of
          *** qtys increasing on Invoices.
          CTRB.ID = 'SOE.INV.AVAIL.CHECK~':STK.BR
          READV DO.CHK FROM CTRBFILE,CTRB.ID,1 ELSE DO.CHK = NO
          * if the control record is not set or we are working with a
          * direct then we don't want to check availabilty.
          IF NOT(DO.CHK) OR LED(33)<1,GEN%> THEN RETURN

          ACT.ID      = 'OE.UPD.QO~CHECK.INV.AVAIL'
          LOCATE ACT.ID IN RESPS<1> SETTING CPOS THEN
             IF NOT(RESPS<2,CPOS,1>) THEN
                MSG.FLAG = NO
                RETURN TO FINISH
             END
          END ELSE
             *** See if the increased Qty is available.
             OE.CHECK.AVAIL OID%,GEN%,LDID%,AV.DT,,,QO.DIFF,YES
             IF AV.DT <= DATE()   THEN RETURN

             *** If not avail, then check the user for auth...
             PRMPT     = '%315':AM:OCONV(AV.DT,'D4/')
             KEY.ID    = 'OE.OVERCOMMIT.STOCK'
             CMNT      = '%316'
             ACTION.ADD.AUTH MSGS,ACT.ID,,PRMPT,,KEY.ID,,CMNT,OID%,GEN%
             MSG.FLAG  = YES
             RETURN TO FINISH
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.INV.CREDIT:*** Check Credit if we're adding qtys to an invoice.
          ACT.ID  = 'CHECK.CREDIT'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF QO.DIFF <= 0         THEN RETURN
          IF MODE%    # 'S'       THEN RETURN
          IF NOT(LED(8)<1,GEN%>)  THEN RETURN
          IF IS.RESERVE THEN RETURN

          *** See if the site is even set up to check the avail of
          *** qtys increasing on Invoices.
          CTRB.ID = 'SOE.INV.CREDIT.CHECK~':STK.BR
          READV DO.CHK FROM CTRBFILE,CTRB.ID,1 ELSE DO.CHK = NO
          IF NOT(DO.CHK)          THEN RETURN

          *** See if the customer is supposed to be on credit hold.
          SOE.CREDIT.CHECK LED(5)<1,GEN%>,NO.OE,,,NO.SHIP,,,OID%,GEN%
          IF NOT(NO.OE) AND NOT(NO.SHIP) THEN
             INV.CREDIT.ID      = 'OE.UPD.QO~SOE.INV.CREDIT.CHECK'
             RESP.CT = DCOUNT(RESPS<1>,VM)
             RESPS<1,RESP.CT+1> = INV.CREDIT.ID
             RETURN
          END

          PRMPT = '%317'
          SOE.CREDIT.RELEASE.CHECK OID%,GEN%,PRMPT,NO,HAS.AUTH,LED(5)<1,GEN%>,1,MSG.FLAG,MSGS,RESPS

          *** Either we need to do some interaction, or we've bombed out
          *** and the user doesn't have authorization...
          IF MSG.FLAG OR NOT(HAS.AUTH) THEN RETURN TO FINISH

          RETURN
*-------------------------------------------------------------------------*
CHECK.CUT: *** Check to see if this product needs to be cut when the user
          *** updates the line item.
          IF MODE%='S' OR MODE% = 'T' THEN
             CUTTABLE = NO

             * VERY important that we check LD(143) here. This will only
             * be set to TRUE if this is a cuttable product that wasn't
             * previously cut due to setup. If we don't check this and
             * just always prompt, the user will be receiving multiple
             * prompts (here and where a new product is being added).
             IF (LD(143) AND JAVA.PROC$) THEN
                * Load in the units of measure that can not be cut.
                NO.CUT.UMS = RAISE(PRD(162))
                CUT.CT     = DCOUNT(NO.CUT.UMS,AM)

                * Loop through them. We cannot do a locate because
                * the data is formatted for an EclipseTable.
                FOR CCT = 1 TO CUT.CT
                   IF (NO.CUT.UMS<CCT,1,1> = "") THEN CONTINUE

                   * If the unit of measure is found, we cannot cut
                   * the product.
                   IF (NO.CUT.UMS<CCT,1,1> = LARGEST.UM) THEN RETURN
                NEXT CCT

                * Check to branch flag in Product Maint.
                PN = LD(1)
                PRD.BR.GET.VAL STK.BR,PN,64,BR.CUT
                BEGIN CASE
                * "1" means the product will NOT be cut.
                CASE (BR.CUT = "1")
                   RETURN

                * "2" means the user will be prompted.
                CASE (BR.CUT = "2")
                   * Setup a prompt in the Action Array.
                   ACT.ID = "CHECK.BR.CUTTABLE"
                   LOCATE ACT.ID IN RESPS<1> SETTING RESP.POS THEN
                      DO.CUT = RESPS<2,RESP.POS,1>
                   END ELSE
                      MSG.FLAG = YES
                      ACTION.ADD.CONFIRM MSGS,ACT.ID,NO,"%380"
                      RETURN TO FINISH
                   END

                   * If the user elected to cut, then update the order.
                   IF DO.CUT THEN
                      CMT  = PRD(1)<1,1,1>[1,30]:" (PN#":LD(1):") "
                      CMT := "will now be cut because the user chose "
                      CMT := "to cut the product after changing the "
                      CMT := "quantity."
                      OE.ADD.COMMENT OID%,LOG.MV%,CMT
                      LD(143) = ""
                      OE.UPDATE.LDID LDID%,OID%,GEN%,LOG.MV%,QSIGN%
                      OE.LI.UPD.CUT MAT OE.VARS,MAT OE.SFLAGS,RESPS
                   END

                * If the product is cuttable at the product (no prompt),
                * then we will add the prompt question to the ACTIONS
                * array *with* an answer of YES (to cut the product). This
                * will trick Solar into openimng up the cut screen for
                * this product.
                CASE OTHERWISE
                   ACT.ID = "CHECK.BR.CUTTABLE"
                   LOCATE ACT.ID IN RESPS<1> SETTING RESP.POS ELSE
                      RESPS = INSERT(RESPS,1,RESP.POS;ACT.ID)
                      RESPS<2,RESP.POS> = YES
                      CMT  = PRD(1)<1,1,1>[1,30]:" (PN#":LD(1):") "
                      CMT := "will now be cut because this product is "
                      CMT := "setup to always be cuttable at the branch."
                      OE.ADD.COMMENT OID%,LOG.MV%,CMT
                      LD(143) = ""
                      OE.UPDATE.LDID LDID%,OID%,GEN%,LOG.MV%,QSIGN%
                      OE.LI.UPD.CUT MAT OE.VARS,MAT OE.SFLAGS,RESPS
                      RETURN
                   END
                END CASE
             END
          END

          RETURN
*-------------------------------------------------------------------------*
ADD.COMMENT:*** When applicable, add a comment to the order change log
          ACT.ID  = 'CHG.LOG.COMMENT'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF NOT(NEW.ORDER%) THEN
             OLD.QO = LD(4) * QSIGN%
             IF LD(1) # OLD.LD(1) AND OLD.LD(1) THEN
                GET.ALL.PRD STK.BR,OLD.LD(1)
                QO.CMT = 'Product Changed From: ':PRD(1)<1,1>
                IQ.TO.ALPHA PLNE(3),PRD(7),OLD.LD(23),OLD.QO,,,,,OLD.QO.ALPHA
                GET.ALL.PRD STK.BR,LD(1)
                QO.CMT := ' To Product: ':PRD(1)<1,1>
             END ELSE
                QO.CMT = 'Product: ':PRD(1)<1,1>
                IQ.TO.ALPHA PLNE(3),PRD(7),LD(23),OLD.QO,,,,,OLD.QO.ALPHA
             END
             QO.CMT<1,1,-1> = 'Order Qty was: ':TRIM(OLD.QO.ALPHA)
             OE.ADD.COMMENT OID%,'',LOWER(QO.CMT)
          END

          RETURN
*-------------------------------------------------------------------------*
UPDATE.QO:*** This actually updates the line item information with the new
          *** order quantity.
          *** Check to see if line we are updating contains a partial kit
          PARTIAL.KIT = NO
          ACT.ID = 'ADDING.PARTIAL.KIT'
          LOCATE ACT.ID IN RESPS<1> SETTING JUNK ELSE
             IF LD(122) # '' THEN
                PARTIAL.KIT = YES
             END ELSE
                PARTIAL.KIT = NO
             END
          END
          *** Don't allow changes to secondary kit line items
          IF LD(124) # '' OR LD(122) # '' THEN
             MATBUILD SV.LD FROM LD
             MATBUILD SV.OLD.LD FROM OLD.LD
             LD.GET LD(124)
             MAT OLD.LD = MAT LD
             MAIN.KIT.QTY = LD(4)
             MATPARSE LD FROM SV.LD
             MATPARSE OLD.LD FROM SV.OLD.LD
             IF MAIN.KIT.QTY # -QO AND LD(4) # '' THEN
                MSG.FLAG = YES
                ACTION.ADD.MSG MSGS,,YES,'%285',,1,,5,3
                RETURN
             END
          END

          * Check if the item is a product relationship parent.
          IF LD(121) # '' THEN PARENT = 1 ELSE PARENT = 0

          * Product relationship checks only apply to sales orders.
          IF MODE% = 'S' THEN
             *** If current line is a parent with product relationships
             *** defined, do not allow the user to change the quantity sign.
             IF (PARENT AND QO+0 < 0) AND NOT(PHANTOM.PROC) THEN
                IF LD(4) AND LD(4)< 0 THEN
                   MSG.FLAG  = YES
                   MSG.TEXT = 'Cannot Reverse Sign On a Parent Item with'
                   MSG.TEXT:= AM:'Product Relationships defined. Please Delete'
                   MSG.TEXT:= AM:'the Line Item and Re-Add with a Negative Qty.'
                   ACTION.ADD.MSG MSGS,,YES,MSG.TEXT,,1,YES,5,3
                   RETURN TO FINISH
                END
             END

             *** If current line is the related child of a parent product,
             *** check to see if it is a required product. If so, do not
             *** allow the quantity to be decreased.
             IF LD(132) # '' THEN PROD.RELS = 1 ELSE PROD.RELS = 0
             IF LD(4) AND QO.DIFF < 0 AND PROD.RELS THEN
                * get ldid for the parent
                PARENT.LDID = LD(132)
                MATBUILD SV.LD FROM LD; * save off ld
                LD.GET PARENT.LDID; * get the parent ld
                PARENT.QO = LD(4)
                * get product relationship information
                GET.TAG.ALONG.INFO LD(1),PARENT.DESC,PNS,QTYS,REQD
                PARENT.DESC = PARENT.DESC[1,20]
                MATPARSE LD FROM SV.LD; * restore the child item ld
                * get the qty and required flag for this child item
                LOCATE LD(1) IN PNS SETTING POS THEN
                   QTY = QTYS<POS>
                   REQ = REQD<POS>
                END ELSE REQ = NO
                *** Make sure that the qty the user is trying to change
                *** to is not less than what the parent product requires.
                *** If it is, display a message to the user and
                *** disallow the change.
                IF REQ AND (QO < (QTY * -PARENT.QO)) THEN
                   MSG.FLAG  = YES
                   MSG.ID    = '%44':AM:PARENT.DESC
                   ACTION.ADD.MSG MSGS,,YES,MSG.ID,,1,YES,5,3

                   RETURN TO FINISH
                END
             END
          END

          LD(4) += QO.DIFF * QSIGN%
          QOPEN  = QO

          *** If open qty changed sign, clear all scheduling
          IF MODE%='T' THEN
             TOL.QTY=(SUMMATION(LD(5)<1,1>)+SUMMATION(LD(6)<1,1>))*QSIGN%
          END ELSE
             TOL.QTY=(SUMMATION(LD(5))+SUMMATION(LD(6)))*QSIGN%
          END

          *** note this will cause problems if some gens are gl closed!
          IF (TOL.QTY<0 AND QOPEN>0) OR (TOL.QTY>0 AND QOPEN<0) THEN
             LD(5)  = ''
             LD(6)  = ''
             LD(7)  = ''
          END
          OLD4          = LD(4)
          DIR.COMMITTED = NO
          IF MODE%='S' AND PRD(105)<1,1> THEN
             GOSUB LOAD.DIR
          END
          IF NOT(DIR.COMMITTED) THEN
             IF PRD(106) AND LED(6)<1,GEN%>#"B" THEN
                OE.GET.DKIT.COMPS OID%,GEN%,STK.BR,LD(1),LDID%
             END
             COMMT = YES
             IF EXEMPT.FLAG THEN
                LOCATE 'NO.COMMT' IN RESPS<2> SETTING POS THEN COMMT = NO
             END
             IF COMMT THEN
                OE.COMMT.QTYS OID%,LDID%,QSIGN%,GEN%,MSGS
             END
          END

          IF OLD4 # LD(4) OR DIR.COMMITTED THEN
             QO    = LD(4) * QSIGN%
             QOPEN = QO
          END

          QS = (SUM(LD(5)<1,GEN%>)+SUM(LD(6)<1,GEN%>)) * QSIGN%
          NO.UET = ''
          IF EXEMPT.FLAG THEN
             LOCATE 'NO.UET' IN RESPS<2> SETTING T.POS THEN NO.UET = 1
          END

          UET.ENABLED.BR = NO
          IF NOT(NO.UET) THEN
             IF UET.ENABLED$ THEN
                CTRB.ID = 'UET.ENABLED~':STK.BR
                READV UET.ENABLED.BR FROM CTRBFILE,CTRB.ID,1 ELSE UET.ENABLED.BR=NO
             END
             IF UET.ENABLED.BR AND LED(6)<1,GEN%> # "B" THEN
                ORD.QTY = LD(4) * QSIGN%
                IF MODE%='S' AND (PRD(3)=1 OR PRD(3)=2) AND ORD.QTY > 0 AND NOT(OLD.LD(4)) THEN
                   GOSUB LOG.UET
                END
             END
          END

          TQS = (SUMMATION(LD(5))+SUMMATION(LD(6))) * QSIGN%
          IF MODE%#'T' AND LD(4)*QSIGN% # TQS THEN
             LD(4) = TQS * QSIGN%
             QO    = TQS
             QOPEN = TQS
          END

          * Check that zone has enough on hand for quantity and
          * warn user if quantity is insufficient
          * This is for when user enters zone on new orders.
          * Usually counter people, as zone is typically entered via
          * RF
          ZONE.PN = LD(1)
          IF NUM(ZONE.PN) AND ZONE.PN NE "" AND ALLOC.ZONE AND NEW.ORDER% THEN
             ZONE.BR = LED(2)<1,GEN%,2>
             * Get the requested qty for this gen
             ZONE.RQ.QTY = LD(4) * QSIGN%
             * Call to get On hand for zone.
             GET.ZONE.LOC ZONE.PN, ZONE.BR, ALLOC.ZONE, ZONE.OH
             * If insufficient quantity in zone, then warn user
             IF ZONE.RQ.QTY > ZONE.OH THEN
                PRMPT.ID = '%802'
                PRMPT.ID<2> = ALLOC.ZONE
                ACTION.ADD.MSG MSGS,,,PRMPT.ID
             END
          END

          IF NOT(DIR.COMMITTED) THEN
             GOSUB PRC.ITEM
             IF MSG.FLAG THEN
                * A prdd.br lock was aquired by OE.COMMT.QTYS, but
                * it should be released since a message was encountered
                * and processing won't continue on this subroutine.
                * Release the PRDD.BR lock acquired by OE.COMMT.QTYS
                STK.BR = LED(2)<1,GEN%,2>

                * First things first, did we lock kit components, if so
                * we need to make sure to unlock them first.
                IF LD(31)#'' THEN
                   CP.CT = DCOUNT(LD(31),VM)
                   FOR J = 1 TO CP.CT
                      PN = LD(31)<1,J>
                      PRDD.BR.UNLOCK STK.BR,PN
                   NEXT J
                END
                IF LD(71)<1,GEN%> THEN
                   LCT = DCOUNT(LD(71)<1,GEN%>,SVM)
                   FOR LN = 1 TO LCT
                      PLIST  = RAISE(RAISE(RAISE(LD(71)<1,GEN%,LN>)))
                      PCT    = DCOUNT(PLIST,AM)
                      FOR PNN = 1 TO PCT
                         CPN = PLIST<PNN>
                         IF NUM(CPN) THEN
                            PRDD.BR.UNLOCK STK.BR,CPN
                         END
                      NEXT PNN
                   NEXT LN
                END
                PN = LD(1)
                PRDD.BR.UNLOCK STK.BR,PN
                RETURN TO FINISH
             END

             *** Need to check line item freight values on a PO
             IF MODE% = 'P' THEN
                *** If order qty changes from positive to negative and
                *** there is line item freight on the item, we need to
                *** prompt user that they cannot change order qty on this
                *** item if the cap method is something other than NONE
                IF OLD.LD(4) > 0 AND LD(4) < 0 AND LD(34)<1,GEN%,1> THEN
                   CAP.METH = LED(93)<1,GEN%,1>[1,1]
                   IF CAP.METH # 'N' AND CAP.METH # '' THEN
                      ACTION.ADD.MSG MSGS,,,'%367'
                      RETURN TO FINISH
                   END
                END ELSE
                   IF NOT(LD(34)<1,GEN%>) AND LD(4) > 0 THEN
                      GOSUB CALC.FF
                   END
                END
             END

             SKIP.REMNANT = ''
             IF EXEMPT.FLAG THEN
                LOCATE 'OE.GET.REMNANT' IN RESPS<2> SETTING TPOS THEN
                   SKIP.REMNANT = 1
                END
             END
             IF NOT(SKIP.REMNANT) THEN
                OE.GET.REMNANT MAT OE.VARS,MSGS,RESPS
             END

             OE.LI.UPDATE MAT OE.VARS,LDID.LIST

             * we need to update the quantity for child products to
             * the parent product
             ACT.ID = 'OE.UPD.QO~PROD.RELS'
             LOCATE ACT.ID IN RESPS<1> SETTING JUNK ELSE
                IF (MODE% = 'S') AND (PARENT) THEN
                   SV.LDID = LDID%
                   MATBUILD SV.LD FROM LD
                   MATBUILD SV.OLD.LD FROM OLD.LD
                   PARENT.QTY = LD(4)

                   GET.TAG.ALONG.INFO LD(1),PARENT.DESC,PNS,QTYS,REQD

                   *** Add an action to change quantity for each of the
                   *** child products.
                   CHG.QO.IDS = LD(121)
                   PROD.REL.CNT = DCOUNT(CHG.QO.IDS,VM)
                   FOR PROD.REL = 1 TO PROD.REL.CNT
                      LD.GET CHG.QO.IDS<1,PROD.REL>
                      LOCATE LD(1) IN PNS SETTING POS THEN
                         PROD.REL.QTY = QTYS<POS>
                         ADD.TYPE     = 'CHNG.QO'
                         MSG.FLAG     = YES
                         DATA         = ''
                         DATA<1,1>    = CHG.QO.IDS<1,PROD.REL>
                         DATA<1,2>    = PROD.REL.QTY * -PARENT.QTY
                         DATA<1,3>    = LD(1)
                         ACTION.ADD MSGS,ADD.TYPE,,,,,DATA
                      END
                   NEXT PROD.REL
                   RESP.CT = DCOUNT(RESPS<1>,VM)
                   RESPS<1,RESP.CT+1> = "OE.UPD.QO~PROD.RELS"
                   LDID% = SV.LDID
                   MATPARSE LD FROM SV.LD
                   MATPARSE OLD.LD FROM SV.OLD.LD
                END
             END

             * we need to update the qty for the rest of the partial kit
             ACT.ID = 'OE.UPD.QO~PARTIAL.KIT'
             LOCATE ACT.ID IN RESPS<1> SETTING JUNK ELSE
                IF PARTIAL.KIT THEN
                   SV.LDID = LDID%
                   MATBUILD SV.LD FROM LD
                   MATBUILD SV.OLD.LD FROM OLD.LD
                   CHANGE.QTY = LD(4)
                   * add an action to update each line item that
                   * contains part of the kit
                   IF PARTIAL.KIT THEN
                      CHG.QO.IDS = LD(122)
                   END
                   PART.CNT = DCOUNT(CHG.QO.IDS,VM)
                   FOR PART = 1 TO PART.CNT
                      LD.GET CHG.QO.IDS<1,PART>
                      IF LD(4) # "" THEN
                         ADD.TYPE  = 'CHNG.QO'
                         MSG.FLAG  = YES
                         DATA      = ''
                         DATA<1,1> = CHG.QO.IDS<1,PART>
                         DATA<1,2> = -CHANGE.QTY
                         DATA<1,3> = LD(1)
                         ACTION.ADD MSGS,ADD.TYPE,,,,,DATA
                         RESP.CT = DCOUNT(RESPS<1>,VM)
                         RESPS<1,RESP.CT+1> = "OE.UPD.QO~PARTIAL.KIT"
                      END
                   NEXT PART
                   LDID% = SV.LDID
                   MATPARSE LD FROM SV.LD
                   MATPARSE OLD.LD FROM SV.OLD.LD
                END
             END
             *** This is put here so that we can know that we have to call
             *** CHECK.SCHEDULE after returning from this GOSUB.  The
             *** reason for this that CHECK.SCHEDULE can open a prompt and
             *** I don't want to have to execute the code in UPDATE.QO
             *** twice in order to get back to the CHECK.SCHEDULE GOSUB.
             RESP.CT = DCOUNT(RESPS<1>,VM)
             RESPS<1,RESP.CT+1> = 'OE.UPD.QO~SCHEDULE'
          END

          IF MODE% = 'P' THEN
             POE.PRORATE.TAX.AMTS OID%,GEN%,LDID%
             GEN.MV = GEN%
             UPDATE.LEDGER.DET OID%,LDID%,QSIGN%,GEN.MV
          END

          * When we are updating the line item, we need to make sure to
          * update the group quantities, because split quantity pricing
          * may have caused the amount being ordered on the current line
          * to change, and this must be taken into consideration.
          IF QSIGN% = 1 THEN GROUP = PRD.BR(23) ELSE GROUP = PRD.BR(24)
          OE.UPD.GROUP GEN%,LDID%,QSIGN%,GROUP

          OE.ITEM.TAG.QTY.CHECK OID%,LDID%,TQS,,MSGS,ERR.MSG
          IF ERR.MSG THEN
             ACTION.ADD.MSG MSGS,,,ERR.MSG,BELL,1,YES
          END

          * Update GL postings for freight if there is line item freight.
          IF MODE% = 'S' AND LED(8)<1,GEN%> AND LD(34)<1,GEN%> THEN
             OE.POST.FGHT.HNDL OID%,GEN%,QSIGN%

             * Set up balancing entries to GL
             GL.IDS  = LED(24)<1,GEN%>
             GL.NOS  = LED(25)<1,GEN%>
             GL.AMTS = LED(26)<1,GEN%>
             OE.UPD.GL.AR OID%,GEN%,GL.IDS,GL.NOS,GL.AMTS
             LED(24)<1,GEN%> = GL.IDS
             LED(25)<1,GEN%> = GL.NOS
             LED(26)<1,GEN%> = GL.AMTS
             OE.UPDATE.INVOICE OID%,GEN%,QSIGN%
          END

FINISH:   * Leave the level we are currently operating on...
          RETURN
FINISH2:  RETURN TO FINISH
*-------------------------------------------------------------------------*
CHECK.DELETE.ITEM: * See if we need to just remove the newly addded L.I.
          INV.CREDIT.ID      = 'OE.UPD.QO~SOE.INV.CREDIT.CHECK'
          LOCATE INV.CREDIT.ID IN RESPS<1> SETTING XX THEN

             SOE.CREDIT.CHECK LED(5)<1,GEN%>,NO.OE,,,NO.SHIP,,,OID%,GEN%
             IF NOT(NO.OE) AND NOT(NO.SHIP) THEN RETURN

             PRMPT = '%317'
             SOE.CREDIT.RELEASE.CHECK OID%,GEN%,PRMPT,NO,HAS.AUTH,LED(5)<1,GEN%>,1,MSG.FLAG,MSGS,RESPS

             *** Either we need to do some interaction, or we've bombed out
             *** and the user doesn't have authorization...
             IF MSG.FLAG THEN RETURN TO FINISH
             IF HAS.AUTH THEN RETURN

             * Take the line off if it breaks their Credit Limit
             OE.DELETE.LINE MAT OE.VARS,YES,DEL.OK
             IF DEL.OK THEN RETURN TO FINISH
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.WIP.SPLIT.QTY: ***
          IF (MODE% # "W") THEN RETURN

          DO.SPLIT = NO
          ACT.ID   = "WIP.SPLIT.QTY"
          LOCATE ACT.ID IN RESPS<1> SETTING NOTHING THEN DO.SPLIT = YES
          IF (QO.DIFF < 0) AND (QO > 0) AND (LED(6)<1,GEN%> # "O") THEN
             DO.SPLIT = YES
          END

          IF DO.SPLIT THEN
             WIP.SPLIT.QTYS MAT OE.VARS,QO.DIFF,LDID.LIST,MSG.FLAG,MSGS,RESPS
             IF MSG.FLAG THEN RETURN TO FINISH
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.SPLIT.QTY:*** Check to see if we'll be splitting this line item into
          *** multiple line items.
          IF IS.RESERVE THEN RETURN
          ACT.ID    = 'CHECK.SPLIT.QTY'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END


          ACT.ID    = 'OE~ORIG.ORD.QTY'
          LOCATE ACT.ID IN RESPS<1> SETTING OPOS THEN
             ORIG.QO = RESPS<2,OPOS>
          END ELSE
             ORIG.QO = 0
          END

          SPLIT.ID  = 'OE.UPD.QO~SPLIT.QTY'
          EXTEND.ID = 'OE.UPD.QO~EXTEND.QTY'
          REPRC.ID  = 'OE.UPD.QO~SPLIT.QTY.REPRICE'

          * Check to see if the SPLIT.ID is found in the responses array.
          LOCATE SPLIT.ID IN RESPS<1> SETTING POS THEN

             * We can now parse out the matrix information (used for
             * Solar) and restore the matrix array that was being used
             * before going back to solar to prompt the user for split
             * quantity pricing.
             MTX = RAISE(RAISE(RAISE(RESPS<2,POS,2>)))

             * Only restore the matrix array if there is currently no
             * valid information in it.
             * This also fixes possible problems with connection pooling.
             * There was instances where the wrong matrix info was loaded
             * from another connection and MA was getting overlayed.
             IF (NOT(MA(1)) OR (JAVA.PROC$ AND (MTX # ""))) THEN
                MATPARSE MA FROM MTX
             END
          END

          * If the split quantity flag is not set, we need not continue.
          IF NOT(MA(2)) THEN RETURN

          * Don't check for split qtys again on the second time around.
          LOCATE REPRC.ID IN RESPS<1> SETTING RPOS THEN RETURN
          LOCATE MOD.QO IN RESPS<1> SETTING RPOS THEN RETURN

          SV.MX     = NO
          LVL       = LD(15)<1,GEN%,5>

          * If the level of the quantity break is greater than one, get
          * the break information (quantity and unit of measure). If the
          * break is one, then there is no quantity or unit of measure to
          * get, so set them to null.
          IF (LVL > 1) THEN
             MQ1    = MA(5)<1,LVL-1>
             MU1    = MA(6)<1,LVL-1>
          END ELSE
             MQ1    = ""
             MU1    = ""
          END

          EQTY      = LD(15)<1,GEN%,8>+0
          IF ORIG.QO THEN
             EQTY += ICONV(ORIG.QO,'MR2')
          END
          ETYP      = LD(15)<1,GEN%,7>
          EXP.SPLIT = NO
          XQO       = LD(4) * QSIGN%

          IF PRD(15) = '' THEN UM.TBL = PLNE(3) ELSE UM.TBL = PRD(15)

          SPLT.QTY = 0
          DO.SPLIT = NO
          DO.REPRC = NO

          * Split quantity pricing works different for G-Type and C-Type
          * matrix cells as it does for all other matrix cells.
          IF ((MA(1) # "C") AND (MA(1) # "G")) THEN

             * If the level is greater than 1, then validate the unit of
             * measure and calculate the split quantity amount.
             IF (LVL > 1) THEN
                VALIDATE.SELL.UM MODE%,UM.TBL,PRD(7),MQ1,MU1,,,,,BQ
                IF NOT(BQ) THEN BQ = 1
                SPLT.QTY = MOD(XQO,BQ)
             END

             * This logic will also check the expire type matrix
             * for split out...
             IF SPLT.QTY = 0 THEN

                * No need to split for UM purposes, nor for Exp Qtys.
                IF EQTY <= 0 THEN RETURN

                BQ       = INT(OCONV(EQTY,'MR2'))
                MATRIX.EXP.QTY.CALC EQTY2,XQO,ETYP,LED(2)<1,GEN%,1>

                * Not over Exp Qty avail, so no need to split.
                IF EQTY2 < BQ THEN RETURN

                * Check for extension of Expire Qtys.
                IF EQTY2 > BQ THEN
                   EXT.SPLT.RETURN = 0
                   GOSUB EXT.SPLT
                   *** Did the Extension, no need to split.
                   IF EXT.SPLT.RETURN = 1 THEN RETURN
                   *** Need to get User Interaction.
                   IF EXT.SPLT.RETURN = 2 THEN
                      MSG.FLAG = YES
                      RETURN TO FINISH
                   END
                END

                * Figure out the split qty due to Exp Qtys.
                SPLT.QTY    = EQTY2-BQ
                MATRIX.ORD.QTY.CALC SQTY,SPLT.QTY,ETYP,LED(2)<1,GEN%,1>
                SPLT.QTY    = SQTY
                IF SPLT.QTY = 0 OR SPLT.QTY = XQO THEN RETURN
                EXP.SPLIT   = YES
                SV.MX       = YES
             END

             * To keep going for the split, there must be something to
             * split.
             IF SPLT.QTY = 0 THEN RETURN
          END ELSE
             * G-Type and C-Type matrix cells do not break when the
             * quantity on the order (for a line) exceeds one of the
             * price breaks on the matrix cell. These matrix cells instead
             * break when a line item is entered on the order where there
             * are two units of measure on the line (e.g. 4bx 3ea). If
             * one of the two units of measure is less than the unit of
             * measure defined in the group (sell or combo), then we want
             * to see if the user wishes to break the lower quantity out
             * onto a new line item.

             IF PRD(15) = "" THEN UM.TBL = PLNE(3) ELSE UM.TBL = PRD(15)
             IQ.TO.ALPHA UM.TBL,PRD(7),LD(23),LD(4),SQ1,SU1,SQ2,SU2
             USE.COMBO = (MA(1) = "C")

             * See if there is a second unit of measure
             IF (SU2 # "") THEN

                * Check to see if either of the two units of measure are
                * less than group unit of measure
                OE.CHK.GROUP.UM LOWER.U1,1,USE.COMBO
                OE.CHK.GROUP.UM LOWER.U2,2,USE.COMBO

                * Depending on which of the two units of measure is less
                * than the group unit of measure, calculate the split
                * quantity accordingly.
                BEGIN CASE
                CASE (LOWER.U1 AND NOT(LOWER.U2))

                   * Because SPLT.QTY is expected to be in the lowest
                   * unit of measure, find the unit of measure being used
                   * and convert it to the lowest.
                   LOCATE SU1 IN UM.TBL<1> SETTING QPOS THEN
                      SPLT.QTY = ABS(SQ1 * (PRD(7)<1,QPOS>))
                   END ELSE
                      SPLT.QTY = ABS(SQ1)
                   END
                   SV.MX = YES
                CASE (LOWER.U2 AND NOT(LOWER.U1))

                   * Because SPLT.QTY is expected to be in the lowest
                   * unit of measure, find the unit of measure being used
                   * and convert it to the lowest.
                   LOCATE SU2 IN UM.TBL<1> SETTING QPOS THEN
                      SPLT.QTY = ABS(SQ2 * (PRD(7)<1,QPOS>))
                   END ELSE
                      SPLT.QTY = ABS(SQ2)
                   END
                   SV.MX    = YES
                CASE OTHERWISE
                   SPLT.QTY = 0
                END CASE
             END

             IF SPLT.QTY = 0 THEN RETURN
          END

          * Do we automatically split, or give the user the option,
          * based on their authorization.
          CHECK.KEY 'SOE.SPLIT.PRICING',,LEVEL

          IF LEVEL > 1 THEN
             LOCATE SPLIT.ID IN RESPS<1> SETTING RPOS THEN
                IF RESPS<2,RPOS,1> THEN DO.SPLIT = YES
                IF NOT(RESPS<2,RPOS,1>) AND EXP.SPLIT THEN DO.REPRC = YES
             END ELSE
                TUNE     = "TWO.TUNE"
                ACTION.ADD.SPLT.QTY MSGS,SPLIT.ID,,"%137",TUNE,,"YN",1,"Y",MAT MA
                MSG.FLAG = YES
                RETURN TO FINISH
             END
          END ELSE
             DO.SPLIT = YES
          END

          NEW.QO = XQO

          * This logic is splitting out the qty for the lowest UM.  When
          * it goes back to START, it will update the LD with the larger
          * UM.
          IF DO.SPLIT THEN
             * This common variable will allow a matrix with an expire
             * quantity less than the current order quantity to be used.
             * See the routine GET.MATRIX to see where this is
             * implimented.
             DO.NOT.SPLIT.QTYS$ = NO
             ADD.TYPE   = 'ADD.LI'

             OE.GET.LDID.LIST LLIST,OID%,GEN%
             LOCATE LDID% IN LLIST<1> SETTING NEW.POS ELSE NEW.POS=''

             ADD.DATA = ''           ;* Data needed for OE.ADD.LINES.
             ADD.DATA<1, 1> = LD(1)                 ;* PN
             ADD.DATA<1, 2> = SPLT.QTY              ;* QO
             ADD.DATA<1, 3> = UM.TBL<1,1>           ;* LARGEST.UM
             ADD.DATA<1, 4> = ''                    ;* ALLOC.ZONE
             ADD.DATA<1, 5> = YES                   ;* INS.LINE
             ADD.DATA<1, 6> = NEW.POS               ;* LINE.NUM
             ADD.DATA<1, 7> = ''                    ;* PRC.OVRD
             ADD.DATA<1, 8> = ''                    ;* CST.OVRD
             ADD.DATA<1, 9> = ''                    ;* ADDL.DATA
             ADD.DATA<1,10> = ''                    ;* INIT.LDID
             ADD.DATA<1,11> = YES                   ;* SKIP.DUP
             ACTION.ADD MSGS,ADD.TYPE,,,,,ADD.DATA
             MSG.FLAG         = YES

             NEW.QO          -= SPLT.QTY
             LARGEST.UM       = MU1
             RESP.CT          = DCOUNT(RESPS<1>,VM) + 1
             RESPS<1,RESP.CT> = MOD.QO
             RESPS<2,RESP.CT> = NEW.QO
          END ELSE
             * This common variable will dis-allow a matrix with an expire
             * quantity less than the current order quantity to be used.
             * See the routine GET.MATRIX to see where this is
             * implimented.
             DO.NOT.SPLIT.QTYS$ = YES
          END

          UPD.LOC = 10
          QO      = NEW.QO

          RESP.CT = DCOUNT(RESPS<1>,VM) + 1
          RESPS<1,RESP.CT> = REPRC.ID

          RETURN TO START
*-------------------------------------------------------------------------*
EXT.SPLT: ***
          *** EQTY2 is the converted QO.  BQ is the converted Remaining
          *** Expire Qty.  ETYP is the 1 character Expire Qty Type.
          IF IS.RESERVE THEN RETURN
          IF MA(2) # 2 THEN RETURN

          EXT.TYP = ''
          BEGIN CASE
          CASE ETYP = 'U';        EXT.TYP = 'Unit'
          CASE ETYP = 'W';        EXT.TYP = 'Weight'
          CASE ETYP = 'L';        EXT.TYP = 'Load Factor'
          CASE ETYP = 'D';        EXT.TYP = 'DFLT LIST'
          END CASE

          EXT.MSG = 'Extend the Remaining Expire Qty of ':BQ:' (based ':AM
          EXT.MSG:= 'on ':EXT.TYP:') to the Order Qty of ':EQTY2:'.'

          LGMV    = GEN%
          LOCATE EXTEND.ID IN RESPS<1> SETTING RPOS THEN
             EXT.OK = RESPS<2,RPOS,1>
             IF NOT(EXT.OK) THEN RETURN
          END ELSE
             KEYID  = 'SOE.SPLIT.PRICING'
             ACTION.ADD.AUTH MSGS,EXTEND.ID,,EXT.MSG,,KEYID,'3',,OID%,LGMV
             EXT.SPLT.RETURN = 2
             MSG.FLAG = YES
             RETURN
          END

          MATBUILD SV.MA FROM MA

          OP.SEL = 'Pricing Matrix'
          OE.SELECT.VIEW.MATRIX OID%,GEN%,LDID%,MODE%,OP.SEL,15,EXT.CC,EXT.PP,EXT.EFF,,EXT.WBR

          EXT.MAD.ID = EXT.WBR:'~':EXT.CC:'~':EXT.PP
          MATREADU MAD FROM MXDFILE,EXT.MAD.ID ELSE MAT MAD=''
          LOCATE EXT.EFF IN MAD(1)<1> BY 'AR' SETTING DX ELSE DX=DX-1

          EXT.OK = NO

          LOOP UNTIL EXT.OK OR DX < 1 DO
             IF MAD(2)<1,DX> < EXT.EFF THEN DX = DX-1 ELSE EXT.OK = YES
          REPEAT

          IF EXT.OK THEN
             *** Raise the used qty, AND the orig exp qty.
             MOD.QTY          = ICONV(OCONV(EQTY2 - BQ,'MR0'),'MR2')
             MAD(3)<1,DX>    += MOD.QTY
             MAD(5)<1,DX>    += MOD.QTY
             LD(15)<1,GEN%,8> = EQTY2

             MATWRITE MAD ON MXDFILE,EXT.MAD.ID
             EXT.SPLT.RETURN = YES
          END

          RELEASE MXDFILE,EXT.MAD.ID
          MATPARSE MA FROM SV.MA

          RETURN
*-------------------------------------------------------------------------*
CHECK.SCHEDULE:*** This will determine in the schedule screen needs to be
               *** opened after the update has been performed.
          IF IS.RESERVE THEN RETURN
          ACT.ID  = 'CHECK.SCHEDULE'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          LOCATE 'OE.UPD.QO~SCHEDULE' IN RESPS<1> SETTING NOTHING ELSE
             * If the 'OE.UPD.QO~SCHEDULE' string isn't in RESPS, then
             * we don't need to check this.  See UPDATE.QO.
             RETURN
          END

          * For purchase orders, quantity shipped and quantity open
          * will be the same regardless if qty is avail or not - we
          * will need to pop the schedule screen if quantity is not
          * avail for users with auth key POE.SCHEDULE level 1.  If
          * quantity not avail for sales/transfers, quantity shipped
          * # quantity ordered.
          CHK.PO = NO
          IF SCHED.ACTIVE% = 1 AND MODE% = 'P' THEN
             STK.TYPE = FIELD(LD(7)<1,1>,'~',1)
             IF STK.TYPE[1,1] = 'S' THEN STK.TYPE = ''
             CALC.AVAIL AVAIL,DATE(),LED(2)<1,GEN%,2>,LD(1),,STK.TYPE
             IF AVAIL < 0 THEN CHK.PO = YES
          END

          * Do not allow sourcing if this is not a Sales Order OR if this
          * is not a Solar process. Sourcing is only available in Solar
          * Sales Order Entry.
          IF (MODE% # "S")   THEN SOURCE.ACTIVE% = NO
          IF NOT(JAVA.PROC$) THEN SOURCE.ACTIVE% = NO

          * Init vars to NO.
          SHOULD.SCHED  = NO
          SHOULD.SOURCE = NO

          QS = (SUM(LD(5)<1,GEN%>)+SUM(LD(6)<1,GEN%>)) * QSIGN%
          BEGIN CASE
          CASE SOURCE.ACTIVE% > 1;                  SHOULD.SOURCE = YES
          CASE QS # QOPEN AND SOURCE.ACTIVE% = 1;   SHOULD.SOURCE = YES
          CASE SCHED.ACTIVE% > 1;                   SHOULD.SCHED  = YES
          CASE QS # QOPEN AND SCHED.ACTIVE% = 1;    SHOULD.SCHED  = YES
          CASE CHK.PO;                              SHOULD.SCHED  = YES
          CASE OTHERWISE;                           SHOULD.SCHED  = NO
          END CASE

          IF SHOULD.SOURCE THEN
             ACTION.ADD MSGS,"SOURCING"
             RESP.CT = DCOUNT(RESPS<1>,VM)
             RESPS<1,RESP.CT+1> = "OE.UPD.QO~SHOULD.SOURCE"
          END ELSE IF SHOULD.SCHED THEN
             ACTION.ADD MSGS,"SCHEDULE"
             RESP.CT = DCOUNT(RESPS<1>,VM)
             RESPS<1,RESP.CT+1> = "OE.UPD.QO~SHOULD.SCHED"
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.DISP.LOC:*** After we've done the scheduling, make sure
          ACT.ID  = 'CHECK.DISP.LOC'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF MODE% # 'S' THEN RETURN
          IF IS.RESERVE THEN RETURN

          *** Like in CHECK.SCHEDULE, parts of this routine need to be
          *** executed only if something else has happened.  Since this
          *** routine is re-entrant, the best way to signal that something
          *** has been done, or needs to be done, is by leaving a little
          *** 'trail' in the RESPS array.
          *** If we are going to do the display location logic, we need
          *** to make sure we have ALREADY GONE to the schedule screen
          *** (if it is called for) because qtys can
          *** get procured or tagged from that screen, enabling us to fill
          *** the (reduced) remainder (after procurement,etc) from display
          *** stock.
          *** Also, wanna make sure we do the 'RETURN TO FINISH' from this
          *** section so that CHECK.SCHEDULE doesn't get called multiple
          *** times.
          LOCATE 'OE.UPD.QO~DID.SCHED' IN RESPS<1> SETTING RPOS ELSE
             LOCATE 'OE.UPD.QO~SHOULD.SCHED' IN RESPS<1> SETTING RPOS THEN
                RESP.CT  = DCOUNT(RESPS<1>,VM)
                RESPS<1,RESP.CT+1> = 'OE.UPD.QO~DID.SCHED'
                MSG.FLAG = YES
                RETURN TO FINISH
             END
          END

          *** We're not really concerned about OPEN Qtys, we wanna know
          *** about NON-Invoiced and NON-Tagged qtys.
          NO.TAG    = YES
          OE.CALC.QOPEN OID%,QSIGN%,,,NO.TAG
          QS        = (SUM(LD(5)<1,GEN%>)+SUM(LD(6)<1,GEN%>)) * QSIGN%

          IF NO.TAG = QS THEN RETURN

          SOE.CHK.DISP.QTY OID%,GEN%,LDID%,QS,NO.TAG,RESULTS
          SOE.VERF.DISP.QTY RESULTS,DO.UPD,MSG.FLAG,MSGS,RESPS

          IF MSG.FLAG THEN RETURN TO FINISH
          IF DO.UPD THEN
             SOE.UPD.DISP.QTY OID%,GEN%,LDID%,QS,NO.TAG
          END

          RETURN
*-------------------------------------------------------------------------*
LOAD.DIR: *
          ACT.ID = 'LOAD.DIR'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING EXEMPT.POS THEN RETURN
          END
          CHECK.KEY 'SOE.DIRECT.EDIT',ENTRY.OK
          IF NOT(ENTRY.OK)        THEN RETURN
          IF IS.RESERVE THEN RETURN
          PO.GID = LED(33)<1,GEN%>
          LOCATE PO.GID IN LED(12)<1> SETTING YGN ELSE YGN = GEN%
          *** If this generation is a direct and the ship-from on this
          *** gen matches the entity associated with this direct product,
          *** then return (this allows the product to be added to this
          *** generation). If this criteria does not hold true, continue to
          *** try to find a valid generation for this product, or prompt
          *** for a new generation.
          IF LED(6)<1,GEN%> = 'D' AND PRD(105)<1,2> = LED(5)<1,YGN> THEN RETURN
          DIR.GENS     = ''
          DIR.GEN.ST   = ''
          *** If this generation is an invoiced direct and the ship gen on
          *** this gen matches the entity, check to see if it's OK to add
          *** to it.
          IF LED(6)<1,GEN%> = 'I' AND PRD(105)<1,2> = LED(5)<1,YGN> THEN
             GOSUB CHK.ADD.OK
             IF ADD.OK THEN
                IF RECONCILED THEN
                   IF LD(4) * QSIGN% > OLD.LD(4) * QSIGN% THEN
                      DIR.GENS<1,-1> = 'Add to DIRECT Current Invoiced Gen'
                   END ELSE
                      DIR.GENS<1,-1> = 'Subtract from DIRECT Current Invoiced Gen'
                   END
                   DIR.GENS<2,-1> = LED(12)<1,GEN%>
                   IF PRD(105)<1,2> THEN
                      DIR.GEN.ST = DCOUNT(DIR.GENS<1>,VM)
                   END
                END ELSE
                   * Not reconciled yet so OK to add. Just return.
                   RETURN
                END
             END
          END

          DIR.AVAIL = CALC.AVAIL(DATE(),STK.BR,LD(1))
          DFLT.PER.GET 'I',PER
          DIR.DISP.AVAIL = (DIR.AVAIL/PER)

          IF DIR.GEN.ST  = '' THEN
             DGN.CT       = DCOUNT(LED(6),VM)
             FOR DGN = 1 TO DGN.CT
                IF LED(6)<1,DGN> = 'D' THEN
                   LOCATE LED(33)<1,DGN> IN LED(12)<1> SETTING YGEN THEN
                      WRK = LED(5)<1,YGEN>
                   END ELSE
                      WRK = ''
                   END
                   IF PRD(105)<1,2> = '' OR PRD(105)<1,2> = WRK THEN
                      DIR.GENS<1,-1> = 'Add to DIRECT Scheduled ':LED(9)<1,DGN>"D4/"
                      DIR.GENS<2,-1> = LED(12)<1,DGN>
                      IF PRD(105)<1,2> AND LED(9)<1,DGN>=LED(9)<1,GEN%> THEN
                         DIR.GEN.ST = DCOUNT(DIR.GENS<1>,VM)
                      END
                   END
                END
             NEXT DGN
             IF DIR.GEN.ST  = '' THEN
                DIR.GENS<1,-1> = 'Create New DIRECT'
                DIR.GEN.ST     = DCOUNT(DIR.GENS<1>,VM)
                IF PRD(105)<1,2> THEN
                   DIR.GENS<1,-1> = 'Create New DIRECT - Show PO Header'
                END
             END
          END
          DIR.GENS<1,-1> = 'Do NOT Ship Item DIRECT'

          PT = ''
          SF = ''

          ** Java will prompt the user for PT,SF if required and pass
          ** it back in.
          LOCATE ACT.ID IN RESPS<1> SETTING RESP.POS THEN
             VAR = RESPS<2,RESP.POS,1>
             PT  = RESPS<2,RESP.POS,2>
             SF  = RESPS<2,RESP.POS,3>
          END ELSE
             DIR.CT = DCOUNT(DIR.GENS<1>,VM)
             IF DIR.CT = 1 THEN
                VAR = DIR.GENS<1,1>
             END ELSE
                MSG.FLAG = YES
                DTITLE = 'Direct Ship Item : '
                DTITLE := PRD(1)<1,1>[1,20]
                DTITLE:= ' **':DIR.DISP.AVAIL:' Available**'
                ACTION.ADD.TABLE MSGS,ACT.ID,DIR.GENS<1>,DIR.GENS<1>,DTITLE
                RETURN TO FINISH2
             END
          END

          IF VAR = '' OR VAR[1,1] = 'D' THEN RETURN

          LOCATE 'SHOW.POE.HEADER' IN RESPS<1> SETTING RESP.POS THEN
             DGEN    = RESPS<2,RESP.POS,1>
             NEW.GEN = RESPS<2,RESP.POS,2>
             GOTO UPD.QO
          END

          MATBUILD SV.CUS  FROM CUS
          MATBUILD SV.CUSS FROM CUSS
          IF VAR[1,1] = 'C' THEN
             * We are about to create a new direct gen, and and we don't
             * have any products on it yet, since this particular product
             * hasn't really been added to the order yet.  Because of this
             * LD is in an interim state (ld4 does not equal ld5+ld6 yet,
             * since we don't know the gen that this call will create.)
             * I could have used an old value of ld4 before calling this,
             * but eterm does not set OID.DATA$<3> in this case, and works
             * correctly.  Java sets OID.DATA$<3> in the calling routine
             * which causes this out of sync ld to create an
             * update.ledger.det error.  So, I'm setting this value to null
             OID.DATA$<3> = ''
             OE.CREATE.NEW.GEN NEW.GEN,OID%,,LED(9)<1,GEN%>,STK.BR,GEN%
             IF PRD(105)<1,2> OR PT#'' OR SF#'' THEN
                IF NOT(SF) AND NOT(PT) THEN
                   SF = PRD(105)<1,2>
                END
                GET.PT.AP PT,SF
                * OID<2> is a flag to OE.CREATE.DIRECT telling it not to
                * activate the New Direct trigger to the vendor.  This is
                * what we want, as OE will activate that trigger when the
                * user exits.
                OID.TEMP = OID%:AM:YES

                * The active LD array has not necessarily been written
                * out to disc...  However, since we are invoking
                * OE.CREATE.DIRECT on a brand new gen, there should be
                * no reason for the currently active LD array to be
                * modified, though OE.CREATE.DIRECT does not protect
                * *this* LD array...  So, save off the current value,
                * and read it back in upon return.
                MATBUILD SV.LD2     FROM LD
                MATBUILD SV.OLD.LD2 FROM OLD.LD
                OE.CREATE.DIRECT OID.TEMP,NEW.GEN,PT,SF,DGEN,LOG.MV%
                MATPARSE LD      FROM SV.LD2
                MATPARSE OLD.LD  FROM SV.OLD.LD2

                IF INDEX(VAR,'Show PO Header',1) THEN
                   MSG.FLAG  = YES
                   DATA      = DGEN
                   DATA<1,2> = NEW.GEN
                   ACTION.ADD MSGS,'SHOW.POE.HEADER',,,,,DATA
                   MATPARSE CUS  FROM SV.CUS
                   MATPARSE CUSS FROM SV.CUSS

                   RETURN TO FINISH2
                END
             END ELSE
                OE.UPDATE.STATUS OID%,NEW.GEN,QSIGN%,LOG.MV%,'D',ERR.MSG
                IF ERR.MSG THEN
                   OE.DEL.GEN OID%,NEW.GEN
                   ACTION.ADD.MSG MSGS,,,ERR.MSG,BELL,,YES,5,5
                   RETURN
                END
                LOCATE LED(33)<1,NEW.GEN> IN LED(12)<1> SETTING DGEN ELSE
                   DGEN = NEW.GEN
                END
             END
          END ELSE
             LOCATE VAR IN DIR.GENS<1> SETTING X ELSE RETURN
             LOCATE DIR.GENS<2,X> IN LED(12)<1> SETTING NEW.GEN ELSE
                NEW.GEN = GEN%
             END
             LOCATE LED(33)<1,NEW.GEN> IN LED(12)<1> SETTING DGEN ELSE
                DGEN    = NEW.GEN
             END
          END

          MATPARSE CUS  FROM SV.CUS
          MATPARSE CUSS FROM SV.CUSS
UPD.QO:   ***

          * Put difference in qty on new gen. Put location on new gen.
          * May be adding to same gen so have to add, not assign diff.
          DIFF = (LD(4) - (SUMMATION(LD(5)) + SUMMATION(LD(6))))
          LD(6)<1,NEW.GEN> += DIFF
          LD(7)<1,NEW.GEN>  = 'D~':LED(1)<1,DGEN>

          SV.GID = LED(12)<1,GEN%>
          GEN%   = NEW.GEN
          IF PRD(106) THEN
             OE.GET.DKIT.COMPS OID%,GEN%,STK.BR,LD(1),LDID%
          END
          GOSUB PRC.ITEM
          IF MSG.FLAG THEN RETURN TO FINISH2

          OE.LI.UPDATE MAT OE.VARS,LDID.LIST

          LOCATE SV.GID IN LED(12)<1> SETTING GEN% ELSE GEN% = 1
          DIR.COMMITTED    = YES

          RETURN
*-------------------------------------------------------------------------*
CHK.ADD.OK:

          RECONCILED = NO
          CHK.GL.POST LED(23)<1,GEN%>,ADD.OK,OID%,LED(6)<1,GEN%>
          IF NOT(ADD.OK) THEN RETURN

          * Make sure PO side is invoiced before checking GL date
          IF LED(8)<1,YGN> THEN
             CHK.GL.POST LED(23)<1,YGN>,ADD.OK,OID%,LED(6)<1,YGN>
             IF NOT(ADD.OK) THEN RETURN
          END

          IN.DATA    = OID%
          IN.DATA<2> = YGN
          OE.CHECK.GEN.PAID IN.DATA,OUT.DATA

          ADD.OK = NOT(OUT.DATA<1>) ; *Is it reconciled?
          IF ADD.OK THEN RETURN     ; *Not reconciled yet.

          * If reconciled, see if it's been paid. If yes, not OK to add.
          RECONCILED = YES
          ADD.OK = NOT(OUT.DATA<2>) ; *Is it paid?

          RETURN
*-------------------------------------------------------------------------*
LOG.UET:  *** Log any UET codes for order quantity updates.

          DIFF    = QS - ORD.QTY
          IF DIFF = 0 THEN RETURN
          UET.PARAMS.QTY.GET OID%,GEN%,LDID%,QPARMS
          BEGIN CASE
          CASE DIFF > 0
             IF QPARMS<2>#'' AND DIFF <= QPARMS<2>        THEN RETURN
             IF QPARMS<4>#'' THEN
                DPERC     = 0
                IF ORD.QTY THEN DPERC = (DIFF/ORD.QTY)*100
                IF DPERC <= QPARMS<4>                     THEN RETURN
             END
          CASE OTHERWISE
             IF QPARMS<1>#'' AND DIFF >= -QPARMS<2>       THEN RETURN
             IF QPARMS<3>#'' THEN
                DPERC     = 0
                IF ORD.QTY THEN DPERC = -(DIFF/ORD.QTY)*100
                IF DPERC <= QPARMS<3>                     THEN RETURN
             END
          END CASE

          ACD          = MODE%:'CKAQ'
          IF LED(33)<1,GEN%> THEN
             ACD := 'D'
          END ELSE
             IF PRD(3) = 2 THEN ACD := 'N'
          END

          DICT.COMMON  = ''
          OID.DATA$    = ''
          OID.DATA$<1> = OID%
          OID.DATA$<2> = GEN%
          OID.DATA$<3> = LDID%
          OID.DATA$<4> = LED(5)<1,GEN%>
          OID.DATA$<5> = LD(1)
          UET.LOG.CHECK ACD,9,DIFF,MSGS

          RETURN
*-------------------------------------------------------------------------*
CALC.FF:  ***
          IF EXEMPT.FLAG THEN
             LOCATE 'UPD.FGHT' IN RESPS<2> SETTING POS THEN RETURN
          END
          IF NOT(NUM(LD(1))) THEN RETURN

          *** They must have freight factor specified.
          FF.METH = (LED(93)<1,GEN%,1>[1,1] = 'F')
          IF NOT(FF.METH) THEN RETURN

          OE.CALC.FF LD(1),LD(8)<1,GEN%>,LED(2)<1,GEN%,1>,FGHT
          LD(34)<1,GEN%> = FGHT

          RETURN
*-------------------------------------------------------------------------*
SHOW.BR.INVS:*** For SOE, check if want to see inv @ other brs, & when...
          ACT.ID  = 'AUTH.SHOW.AVAIL'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF MODE% # 'S' THEN RETURN
          IF IS.RESERVE THEN RETURN

          CTRB.ID = 'AUTO.OE.SHOW.AVAIL~':STK.BR
          READV SHOW.AVAIL FROM CTRBFILE,CTRB.ID,1 ELSE SHOW.AVAIL = ''

          AVAIL    = YES
          CTRL.SET = SHOW.AVAIL[1,1]

          *** If control record is set to display branch availablity
          *** when there is none availalble in current shipping branch,
          *** determine first available shipping date of this item.
          IF CTRL.SET = 'U' THEN
             OE.CHECK.AVAIL.ALL OID%,LDID%,AVAIL.DATE
             IF AVAIL.DATE > LED(9)<1,GEN%> AND AVAIL.DATE > DATE() THEN
                *** Make sure the the product is available in time for
                *** the ship date or for today (whichever is later).
                AVAIL = NO
             END
          END

          IF USER.ID="MFORE" THEN
          AVAIL = YES
          END

          *** If the setting is always or the item's not available and
          *** that's when they want to see the other branches available
          *** quantities, set up the message code for the client.
          IF CTRL.SET = 'A' OR (CTRL.SET = 'U' AND NOT(AVAIL)) THEN
             DATA      = LD(1)
             DATA<1,2> = STK.BR
             DATA<1,3> = QO
             ACTION.ADD MSGS,'AUTO.SHOW.AVAIL',,,,,DATA
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.RETURN:*** This determines if SOE.RETURN.CHECK needs to be called
             *** and if so, adds an action array onto the stack in order
             *** to make that call.
          UT.OPEN.FILE "LEDGER.GPS",LEDGPSFILE,ERR.MSG
          READV CHK.OUT.DATE FROM LEDGPSFILE,OID%,25 ELSE CHK.OUT.DATE = ""
          IF CHK.OUT.DATE # "" THEN RETURN


          ACT.ID  = 'SOE.RETURN.CHECK'
          RETURN.CHECK = TRANS('LEDGER.GPS',OID%,7,'X')
          IF RETURN.CHECK="1" THEN RETURN


          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF MODE% # 'S' THEN RETURN ;* Only Sales Orders
          IF QO >= 0     THEN RETURN ;* Only Returns
          !IF PRD(3) = 3  THEN RETURN ;* No MiscChrg Items
          *we let the soe check return falls through here
          *because OE.CHECK.PIL.BODY will check the control record to see
          *if we want to pop the SOE check verification screen or not.

          IF IS.RESERVE THEN RETURN

          ACT.ID = 'OE.UPD.QO~CHECK.RETURN'
          LOCATE ACT.ID IN RESPS<1> SETTING NOTHING ELSE
             DISP.OK = YES
             *we shouldn't add the action to the array if the item should
             *be excluded from the return verification check.
             *for some reason, we did that logic in OE.PIL.CHECK.BODY.
             IF LED(6)<1,GEN%> = 'B' THEN
                SOE.CHECK.RETURN.DISP DISP.OK
             END
             IF DISP.OK THEN
                ACTION.ADD MSGS,'SOE.RETURN.CHECK',ACT.ID
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.DETAIL.LOT:***
          ACT.ID  = 'DETAIL.LOT'
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          IF MODE% #'S'           THEN RETURN
          IF LED(6)<1,GEN%> = 'B' THEN RETURN
          IF LED(6)<1,GEN%> = 'I' THEN RETURN
          IF LED(6)<1,GEN%> = 'X' THEN RETURN
          IF LED(6)<1,GEN%> = 'Y' THEN RETURN
          IF NOT(DISP.LOT.SEL$)   THEN RETURN
          IF LD(4) > 0            THEN RETURN
          IF IS.RESERVE THEN RETURN

          *** Check to see if this item is a detail lot.
          IF PRC.BR = STK.BR THEN
             LOC.TYPE = PRD.BR(11)
          END ELSE
             GET.PRD.BR.VAL STK.BR,LD(1),11,LOC.TYPE
          END
          IF LOC.TYPE # 'D' THEN RETURN

          ACTION.ADD MSGS,'DETAIL.LOT'

          RETURN
*-------------------------------------------------------------------------*
PRC.ITEM: *** This will price the product on the current line item for
          *** this order.  UNFORTUNATELY, there is one problem: GP Checks.
          *** The GP check happens so many levels below the OE.PRICE.ITEM
          *** call that it would be impossible to re-write OE.PRICE.ITEM
          *** w/o re-writing a huge portion of everything.  So, this case
          *** is an exception.
          ***
          *** When running using eterm, the GP check happens like it used
          *** to:  windows are opened, inputs occure, etc.
          ***
          *** When running using solar eclipse, the GP check doesn't
          *** happen until later.  If a gp check is needed, then a
          *** record is written to the control file that is then read
          *** after OE.PRICE.ITEM returns.  The gp check is converted
          *** into an action, this update returns, solar client does
          *** UI stuff & sets RESPS, and then this update is called
          *** again.  If the GP check failed, then the changes to the
          *** prices are un-done and this update continues.

          LOCATE MOD.QO IN RESPS<1> SETTING RPOS THEN RETURN

          ACT.ID = "POE.MATRIX"
          LOCATE ACT.ID IN RESPS<1> SETTING POE.RPOS ELSE
             IF NOT(EXEMPT.FLAG) AND MODE% = 'P' AND OPEN.VEN.MATRIX$ THEN
                ACTION.ADD MSGS,ACT.ID,,,,,QO
                MSG.FLAG = YES
                RETURN
             END
             POE.RPOS = 0
          END

          ACT.ID = 'OE.UPD.QO~PRC.ITEM'
          NO.GP.CHECK = NO
          LOCATE ACT.ID IN RESPS<1> SETTING PRC.RPOS ELSE PRC.RPOS = 0

          IF PRC.RPOS THEN
             IF NOT(RESPS<2,PRC.RPOS,1>) THEN
                IF (LD(1) # OLD.LD(1) AND OLD.LD(1) = '') THEN
                   OE.DELETE.LINE MAT OE.VARS,YES
                   RETURN
                END
                OLD.VALUE = RESPS<2,PRC.RPOS,2>
                JAVA.OE.UNDO.GP OID%,GEN%,QSIGN%,LDID%,'PRICE',OLD.VALUE,YES
             END
             NO.GP.CHECK = YES
          END

          IF (POE.RPOS) THEN
             IQPRC    = RESPS<2,POE.RPOS,1>
             PRC.DATA = RESPS<2,POE.RPOS,2>
          END ELSE
             IQPRC    = ""
             PRC.DATA = ""
          END

          NO.RECOST = ''
          NO.RECOST<2> = NO.GP.CHECK
          OE.PRICE.ITEM OID%,GEN%,LDID%,LD(1),QO,QSIGN%,GROUP,LOG.MV%,REDISP,LDID.LIST,,,NO.RECOST,,,,,IQPRC,PRC.DATA

          IF REDISP THEN
             LOCATE 'REDISP.LI' IN RESPS<1> SETTING NOTHING ELSE
                RESPS<1,-1> = 'REDISP.LI'
             END
          END

          CTRL.ID = 'GP.ERRORS~':USER.ID:'~':OID%
          READ GP.INFO FROM CTRLFILE,CTRL.ID THEN
             DELETE CTRLFILE, CTRL.ID
             IF NOT(NO.GP.CHECK) THEN
                MSG.FLAG = YES
                ACTION.ADD MSGS,'GP.CHECK',ACT.ID,,,,LOWER(LOWER(GP.INFO))
             END
          END

          RETURN
*-------------------------------------------------------------------------*
CHECK.BRANCH.AUTH: *** Check that the user us authed for branches on the GEN
                   *** the line item is on.
          ACT.ID = "CHECK.BRANCH.AUTH"
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          * This check is only needed on Sales Orders open generations
          * which are the only cases where we might access line items
          *that are a different GEN with different branches.
          IF MODE% # "S" THEN RETURN
          * Statuses I,$,X, and Y are not open
          IF INDEX("I$XY",LED(6)<1,GEN%>,1) THEN RETURN
          IF IS.RESERVE THEN RETURN

          * Find the GEN this line item is on
          FIND LDID% IN LED(48) SETTING LDID.AM,LDID.GEN,LDID.SVM ELSE
             LDID.GEN = GEN%
          END

          *Check is the user is authed for the line item's Gen's branches
          OE.USER.BRANCH.AUTH MODE%,LDID.GEN,AUTH.MSG

          *Display Branch authorization error message id not authed
          IF AUTH.MSG THEN
             ACTION.ADD.MSG MSGS,,YES,AUTH.MSG,,,YES
             RETURN TO FINISH
          END
          RETURN

*-------------------------------------------------------------------------*
CHECK.CUSTOM: *** check for any custom programs that might need to be run
          ACT.ID = "CUSTOM.MOD"
          IF EXEMPT.FLAG THEN
             LOCATE ACT.ID IN RESPS<2> SETTING POS THEN RETURN
          END
          OE.LI.GET.ADDL.CUSTOM OID%,GEN%,LDID%,MSGS

          RETURN
*-------------------------------------------------------------------------*
!TSMITH~12/22/16~10:35
